<?php

namespace app\admin\controller;

use app\common\model\BlackCardModel;
use app\common\model\BlackDeviceModel;
use app\common\model\BlackIpModel;
use app\common\model\BlackKeywordModel;
use app\common\model\UserLogModel;
use app\common\model\UserModel;
use gogrpc\AccountServer;
use gogrpc\LiveServer;
use think\Db;
use think\facade\Cache;
use think\facade\Request;
use Box\Spout\Reader\Common\Creator\ReaderEntityFactory;
use app\common\model\BlackBankModel;

class SecurityController extends BaseController
{
    public function black()
    {
        return $this->fetch();
    }

    public function add()
    {
        $type = Request::param("type");
        $this->assign("type", $type);
        switch ($type) {
            case 1:
                $name = '设备号';
                $post = 'device';
                break;
            case 2:
                $name = 'IP地址';
                $post = 'ip';
                break;
            case 3:
                $name = '银行卡';
                $post = 'bank';
                break;
            case 4:
                $name = '关键词';
                $post = 'keyword';
                break;
            default:
                $name = '身份证';
                $post = 'card';
        }
        $this->assign("name", $name)
            ->assign("post", $post);
        return $this->fetch();
    }

    public function upload()
    {
        $type = Request::param('type', 0);
        $this->assign('type', $type);
        return $this->fetch();
    }

    public function appedit()
    {
        $type = Request::param("type");
        $this->assign("type", $type);
        switch ($type) {
            case 1:
                $ads = BlackDeviceModel::get(Request::param('id'));
                $this->assign("name", '设备号');
                $this->assign("post", 'device');
                break;
            case 2:
                $ads = BlackIpModel::get(Request::param('id'));
                $this->assign("name", 'IP地址');
                $this->assign("post", 'ip');
                break;
            case 3:
                $ads = BlackBankModel::get(Request::param('id'));
                $this->assign("name", '银行卡');
                $this->assign("post", 'bank');
                break;
            case 4:
                $ads = BlackKeywordModel::get(Request::param('id'));
                $this->assign("name", '关键词');
                $this->assign("post", 'keyword');
                break;
            default:
                $ads = BlackCardModel::get(Request::param('id'));
                $this->assign("name", '身份证');
                $this->assign("post", 'card');
        }
        $this->assign("adsInfo", $ads);
        return $this->fetch();
    }

    public function put()
    {
        // 获取表单上传文件 例如上传了001.jpg
        $file = request()->file('file');

        // 移动到框架应用根目录/public/uploads/ 目录下
        if ($file) {
            $info = $file->move("{$_SERVER['DOCUMENT_ROOT']}/uploads");
            if ($info) {
                /*echo $info->getExtension();
                echo $info->getPathName();*/
                $reader = ReaderEntityFactory::createReaderFromFile($info->getPathName());
                $reader->open($info->getPathName());
                $total = 0;
                foreach ($reader->getSheetIterator() as $sheet) {
                    foreach ($sheet->getRowIterator() as $row) {
                        $cells = $row->getCells();
                        $total++;
                    }
                }
                return self::bulidSuccess(['total' => $total, 'success' => $total, 'duplicate' => $total, 'error' => $total, 'file' => $info->getSaveName()]);
            }
        }
        return self::bulidFail();
    }

    public function getlist()
    {
        $type  = Request::param("type");
        $page  = Request::param("page");
        $limit = Request::param("limit");

        $page  = intval($page) < 1 ? 1 : $page;
        $limit = intval($limit) < 1 ? 100 : $limit;

        switch ($type) {
            case 1:
                $model = BlackDeviceModel::field('*');
                if ($device = Request::param('device', false)) {
                    $model->whereLike('device', '%' . trim($device) . '%');
                }
                if ($start_time = Request::param('start_time', false)) {
                    $model->where('add_time', '>=', $start_time);
                }
                if ($start_time = Request::param('end_time', false)) {
                    $model->where('add_time', '<=', $start_time);
                }

                if ($nick = Request::param('nick_name', false)) {
                    if (!$ids = UserModel::where(['account' => $nick])->find()) {
                        return static::bulidFail("未查询到相关数据");
                    }
                    $model->where('device', '=', $ids->device_info);
                }

                $count = $model->count();
                $data  = $model->with('admin')->order("id desc")->page($page, $limit)->select();
                if ($data) {
                    $devices     = array_column($data->toArray(), 'device');
                    $accountInfo = UserModel::whereIn('device_info', $devices)->fieldRaw('device_info,group_concat(account) as accounts')->group('device_info')->select()->toArray();
                    $devicesFix  = array_column($accountInfo, null, 'device_info');
                    foreach ($devicesFix as &$value) {
                        if (!empty($value['accounts'])) {
                            $value['accounts'] = $this->userinfo->roleid == 11 ? $value['accounts'] : preg_replace('/(\d{3})\d{4}(\d{4})/', '$1****$2', $value['accounts']);

                        }
                    }
                    foreach ($data as &$item) {
                        $item->devices = $devicesFix[$item->device] ?? [];
                    }
                }
                break;
            case 2:
                $model = BlackIpModel::field('*');
                if ($device = Request::param('device', false)) {
                    $model->whereLike('device', '%' . trim($device) . '%');
                }
                if ($start_time = Request::param('start_time', false)) {
                    $model->where('add_time', '>=', $start_time);
                }
                if ($start_time = Request::param('end_time', false)) {
                    $model->where('add_time', '<=', $start_time);
                }

                if ($ip = Request::param('ip', false)) {
                    $model->whereLike('ip', "%$ip%");
                }
                $nick = Request::param('nick_name', false);
                if ($nick) {
                    $ip_arr = UserModel::where('account', 'like', $nick . '%')->column('last_ip');
                    $model->whereIn('ip', $ip_arr);
                }
                $count = $model->count();
                $data  = $model->with('admin')->order("id desc")->page($page, $limit)->select();
                if ($data) {
                    $devices     = array_column($data->toArray(), 'ip');
                    $accountInfo = UserModel::whereIn('last_ip', $devices)->fieldRaw('last_ip,group_concat(account) as accounts')->group('last_ip')->select()->toArray();
                    $devicesFix  = array_column($accountInfo, null, 'last_ip');
                    foreach ($data as &$item) {
                        $item->ips = $devicesFix[$item->ip] ?? [];
                    }
                }

                break;
            case 3:
                $model = BlackBankModel::field('*');

                if ($bank_no = Request::param('bank_no', false, 'trim')) {
                    $model->where('bank', 'like', '%' . $bank_no . '%');
                }

                if ($start_time = Request::param('start_time', false)) {
                    $model->where('add_time', '>=', $start_time);
                }
                if ($start_time = Request::param('end_time', false)) {
                    $model->where('add_time', '<=', $start_time);
                }
                $count = $model->count('id');
                $data  = $model->with('admin')->order("id desc")->page($page, $limit)->select();
                break;
            case 4:
                $model = BlackKeywordModel::field('*');

                if ($kword = Request::param('kword', false, 'trim')) {
                    $model->where('keyword', 'like', '%' . $kword . '%');
                }
                if ($start_time = Request::param('start_time', false)) {
                    $model->where('add_time', '>=', $start_time);
                }
                if ($start_time = Request::param('end_time', false)) {
                    $model->where('add_time', '<=', $start_time);
                }

                $count = $model->count();
                $data  = $model->with('admin')->page($page, $limit)->order("id desc")->select();
                break;
            case 5:
                $model = BlackCardModel::field('*');

                if ($card_no = Request::param('card_no', false, 'trim')) {
                    $model->where('card', 'like', '%' . $card_no . '%');
                }

                if ($start_time = Request::param('start_time', false)) {
                    $model->where('add_time', '>=', $start_time);
                }
                if ($start_time = Request::param('end_time', false)) {
                    $model->where('add_time', '<=', $start_time);
                }
                $count = $model->count();
                $data  = $model->with('admin')->order("id desc")->page($page, $limit)->select();
                break;
        }

        if (count($data)) {
            return json(["code" => 0, "msg" => "", "data" => $data, "count" => $count]);
        }
        return self::bulidFail("未查询到相关数据");
    }


    public function appadd_post()
    {
        $type = Request::param("type");
        switch ($type) {
            case 1:
                if (!$device = trim($this->post('device', ''))) {
                    return static::bulidFail('设备号不能为空');
                }

                $ads = new BlackDeviceModel();
                $ads->device = $device;
                $ads->note = trim($this->post('note', ''));
                $ads->admin_id = $this->userinfo->id;
                $ads->add_time = date("Y-m-d H:i:s");
                if ($ads->save()) {
                    
                    $users = UserModel::field('id,online_status')->where('device_info', $ads->device)->select()->toArray();
                    $account_server = new AccountServer();
                    foreach ($users as $user) {
                        if ($user['online_status'] == 1) {
                            try {
                                $account_server->logout($user['id']);
                            }catch (\Exception $exception){
                            }
                        }
                    }
                    // 记录日志
                    $log_content = "添加设备号黑名单，ID：{$ads->id}，设备号：{$ads->device}";
                    parent::addAdminLog($log_content);
                    return self::bulidSuccess();
                }
                break;
            case 2:
                $ads           = new BlackIpModel(Request::param());
                $ads->admin_id = $this->userinfo->id;
                $ads->add_time = date("Y-m-d H:i:s");
                if ($ads->save()) {
                    // 记录日志
                    $log_content = "添加IP黑名单，ID：{$ads->id}，IP：{$ads->ip}";
                    parent::addAdminLog($log_content);
                    return self::bulidSuccess();
                }
                break;
            case 3:
                $ads           = new BlackBankModel(Request::param());
                $ads->admin_id = $this->userinfo->id;
                $ads->add_time = date("Y-m-d H:i:s");
                if ($ads->save()) {
                    // 记录日志
                    $log_content = "添加银行卡黑名单，ID：{$ads->id}，IP：{$ads->bank}";
                    parent::addAdminLog($log_content);
                    return self::bulidSuccess();
                }

                break;
            case 4:
                $keyword = Request::param('keyword', '', 'trim');
                if (mb_strlen($keyword) < 1) {
                    return self::bulidFail('请输入关键词');
                }

                // 查询是否存在
                $keys = BlackKeywordModel::where('keyword', $keyword)->find();
                if ($keys && $keys->keyword == $keyword) {
                    return self::bulidFail('关键词黑名单已存在');
                }

                $ads           = new BlackKeywordModel(Request::param());
                $ads->admin_id = $this->userinfo->id;
                $ads->add_time = date("Y-m-d H:i:s");

                // 请求grpc接口处理，完成之后在写入到库
                $live_server = new LiveServer();
                $res         = $live_server->addSensitive($ads->keyword);
                if (!$res) {
                    return self::bulidFail('添加失败');
                }

                if ($ads->save()) {
                    // 记录日志
                    $log_content = "添加关键词黑名单，ID：{$ads->id}，关键词：{$ads->keyword}";
                    parent::addAdminLog($log_content);
                    return self::bulidSuccess();
                }

                // 入库失败删除grpc接口里面的内容
                $live_server->addSensitive($ads->keyword, 0);
                break;
            default:
                $ads           = new BlackCardModel(Request::param());
                $ads->admin_id = $this->userinfo->id;
                $ads->add_time = date("Y-m-d H:i:s");
                if ($ads->save()) {
                    // 记录日志
                    $log_content = "添加身份证黑名单，ID：{$ads->id}，身份证号：{$ads->card}";
                    parent::addAdminLog($log_content);
                    return self::bulidSuccess();
                }
        }

        return self::bulidFail();
    }

    public function import_file()
    {
        set_time_limit(0);
        $file = request()->file('file');
        $type = Request::param("type");


        if (!in_array($type, [1, 2, 3, 4])) {
            return self::bulidFail('暂时还未开放改模块的批量导入功能');
        }
        if (empty($file)) {
            return self::bulidFail('请选择需要上传的文件');
        }

        $info = $file->move("{$_SERVER['DOCUMENT_ROOT']}/uploads");
        if (!$info) {
            return self::bulidFail('上传失败');
        }

        $reader = ReaderEntityFactory::createReaderFromFile($info->getPathName());
        $reader->open($info->getPathName());
        $statis = [
            'total'     => 0,
            'success'   => 0, // 成功
            'duplicate' => 0,//重复
        ];
        // grpc关键词数组
        $black_leyword = array();
        // 入库数组
        $insert_data = array();

        foreach ($reader->getSheetIterator() as $sheet) {
            foreach ($sheet->getRowIterator() as $k => $row) {
                if ($k == 1) {
                    continue;
                }
                $statis['total'] += 1;

                $cells = $row->getCells();
                if (mb_strlen($cells[0]->getValue()) < 1) {
                    continue;
                }

                $now = date('Y-m-d H:i:s', time());

                switch ($type) {
                    case 4:
                        $keyword = str_replace(',', '', $cells[0]->getValue());

                        // 查询是否存在
                        if (BlackKeywordModel::where('keyword', $keyword)->field('id')->find()) {
                            $statis['duplicate'] += 1;
                            break;
                        }
                        $add_data = [
                            'keyword'     => $keyword,
                            'note'        => isset($cells[1]) ? $cells[1]->getValue() : '',
                            'add_time'    => $now,
                            'modify_time' => $now,
                            'admin_id'    => $this->userinfo->id,
                        ];
                        array_push($black_leyword, $keyword);
                        array_push($insert_data, $add_data);
                        unset($add_data, $keyword);
                        break;
                }
            }
        }

        if ($statis['total'] < 1) {
            return self::bulidFail();
        }

        if ($type == 4) {
            // 先请求grpc
            $live_server = new LiveServer();
            $res         = $live_server->addSensitive($black_leyword);
            if (!$res) {
                return self::bulidFail();
            }

            $balck_keyword_model = new BlackKeywordModel();
            if (!$balck_keyword_model->saveAll($insert_data)) {
                $live_server->addSensitive($black_leyword, 0);
                return self::bulidFail();
            }

            $statis['success'] = count($black_leyword);
            // 记录日志
            $log_content = "批量导入关键词黑名单，共：{$statis['total']}条，成功导入：{$statis['success']}条";
            parent::addAdminLog($log_content);
            return self::bulidSuccess($statis);
        }
        return self::bulidFail();
    }

    public function appedit_post()
    {
        $type = Request::param("type");
        $id   = Request::param('id');
        switch ($type) {
            case 1:
                $ads = BlackDeviceModel::get($id);
                if (Request::param('dis_account', false)) {
                    UserModel::where('device_info', '=', Request::param('device'))->update([
                        'status' => Request::param('dis_account')
                    ]);
                }
                $ads->device      = Request::param('device');
                $ads->note        = Request::param('note');
                $ads->modify_time = date("Y-m-d H:i:s");
                $ads->admin_id    = $this->userinfo->id;
                if ($ads->save()) {
                    // 记录日志
                    $log_content = "修改设备号黑名单，ID：{$ads->id}，设备号：{$ads->device}";
                    parent::addAdminLog($log_content);
                    return self::bulidSuccess();
                }
                break;
            case 2:
                $ads              = BlackIpModel::get($id);
                $ads->ip          = Request::param('ip');
                $ads->note        = Request::param('note');
                $ads->modify_time = date("Y-m-d H:i:s");
                $ads->admin_id    = $this->userinfo->id;
                if ($ads->save()) {
                    // 记录日志
                    $log_content = "修改IP黑名单，ID：{$ads->id}，IP：{$ads->ip}";
                    parent::addAdminLog($log_content);
                    return self::bulidSuccess();
                }
                break;
            case 3:
                $ads              = BlackBankModel::get($id);
                $ads->bank        = Request::param('bank');
                $ads->note        = Request::param('note');
                $ads->modify_time = date("Y-m-d H:i:s");
                $ads->admin_id    = $this->userinfo->id;
                if ($ads->save()) {
                    // 记录日志
                    $log_content = "修改银行卡黑名单，ID：{$ads->id}，IP：{$ads->bank}";
                    parent::addAdminLog($log_content);
                    return self::bulidSuccess();
                }
                break;
            case 4:
                $keyword = Request::param('keyword', '', 'trim');
                if (mb_strlen($keyword) < 1) {
                    return self::bulidFail('请输入关键词');
                }
                $ads = BlackKeywordModel::get($id);

                $live_server = new LiveServer();

                // 查询是否存在
                $c_where = [
                    ['id', '<>', $ads->id],
                    ['keyword', '=', $keyword],
                ];
                $exists  = BlackKeywordModel::where($c_where)->find();
                if ($exists) {
                    return self::bulidFail('关键词黑名单已存在');
                }

                // 请求grpc接口处理
                $live_server->addSensitive($ads->keyword, 0);

                $ads->keyword     = $keyword;
                $ads->note        = Request::param('note');
                $ads->modify_time = date("Y-m-d H:i:s");
                $ads->admin_id    = $this->userinfo->id;
                // 请求grpc接口处理
                $res = $live_server->addSensitive($ads->keyword);
                if (!$res) {
                    return self::bulidFail();
                }

                if ($ads->save()) {
                    // 记录日志
                    $log_content = "修改关键词黑名单，ID：{$ads->id}，关键词：{$ads->keyword}";
                    parent::addAdminLog($log_content);
                    return self::bulidSuccess();
                }

                break;
            default:
                $ads              = BlackCardModel::get($id);
                $ads->card        = Request::param('card');
                $ads->note        = Request::param('note');
                $ads->modify_time = date("Y-m-d H:i:s");
                $ads->admin_id    = $this->userinfo->id;
                if ($ads->save()) {
                    // 记录日志
                    $log_content = "修改身份证黑名单，ID：{$ads->id}，身份证号：{$ads->card}";
                    parent::addAdminLog($log_content);
                    return self::bulidSuccess();
                }
        }

        return self::bulidFail();
    }

    public function appdel_post()
    {
        $type = Request::param("type");
        $id   = Request::param('id');
        switch ($type) {
            case 1:
                $ads = BlackDeviceModel::get($id);
                if (BlackDeviceModel::destroy($id)) {
                    // 记录日志
                    $log_content = "删除设备号黑名单，ID：{$ads->id}，设备号：{$ads->device}";
                    parent::addAdminLog($log_content);
                    return self::bulidSuccess();
                }
                break;
            case 2:
                $ads = BlackIpModel::get($id);
                if (BlackIpModel::destroy($id)) {
                    // 记录日志
                    $log_content = "删除IP黑名单，ID：{$ads->id}，IP：{$ads->ip}";
                    parent::addAdminLog($log_content);
                    return self::bulidSuccess();
                }
                break;
            case 3:
                $ads = BlackBankModel::get($id);
                if (BlackBankModel::destroy($id)) {
                    // 记录日志
                    $log_content = "删除银行卡黑名单，ID：{$ads->id}，IP：{$ads->bank}";
                    parent::addAdminLog($log_content);
                    return self::bulidSuccess();
                }
                break;
            case 4:
                $ads = BlackKeywordModel::get($id);

                // 请求grpc接口处理
                $live_server = new LiveServer();
                $live_server->addSensitive($ads->keyword, 0);

                if (BlackKeywordModel::destroy($id)) {
                    // 记录日志
                    $log_content = "删除关键词黑名单，ID：{$ads->id}，关键词：{$ads->keyword}";
                    parent::addAdminLog($log_content);
                    return self::bulidSuccess();
                }

                break;
            default:
                $ads = BlackCardModel::get($id);
                if (BlackCardModel::destroy($id)) {
                    // 记录日志
                    $log_content = "删除身份证黑名单，ID：{$ads->id}，身份证号：{$ads->card}";
                    parent::addAdminLog($log_content);
                    return self::bulidSuccess();
                }
        }
        return self::bulidFail();
    }

}